// 导入词法分析器Lexer，用于解析音乐记谱语言
import Lexer from './Lexer'

// 导入Head和Body组件，分别代表乐谱的头部信息和主体内容
import Head from './Head'
import Body from './Body'

// 导入和Mxl格式相关的转换函数，支持从Mxl导入和导出乐谱
import fromMxl from './fromMxl'
import toMxl from './toMxl'

// 导入Player用于播放乐谱，Style用于管理样式，defaultStyle提供默认样式配置
import Player from '../player/Player'
import Style from '../utils/Style'
import defaultStyle from '../layout/default.style'

// 导入ScoreLayout用于布局乐谱，scoreElement用于生成乐谱元素
import ScoreLayout from '../layout/ScoreLayout'
import scoreElement from '../view/scoreElement'

/**
 * 定义Score类，表示一个完整的乐谱
 * 乐谱由可选的空白字符、头部信息(Head)和主体部分(Body)组成
 **/
export default class Score {
  constructor(score = {}) {
    this.name = 'score'
    // 如果输入为字符串，则解析该字符串，否则使用提供的Head和Body实例化乐谱
    if (typeof score === 'string') {
      this.parse(new Lexer(score))
    } else {
      this.head = new Head(score.head)
      this.body = new Body(score.body)
    }

    // 初始化默认样式和播放器
    this.style = new Style(defaultStyle)
    this.player = new Player(this)
  }

  // 解析函数，用于解析输入的字符串为乐谱对象
  parse(lexer) {
    lexer.skipWhite() // 跳过空白字符
    this.head = new Head(lexer) // 解析头部信息
    this.body = new Body(lexer) // 解析主体内容

  }

  // 添加一个或多个样式到乐谱
  addStyle() {
    const styles = Array.from(arguments)
    styles.forEach(style => this.style.add(style))
    return this
  }

  // 渲染乐谱为可视化的HTML元素
  render() {
    return scoreElement(new ScoreLayout(this))
  }

  // 控制乐谱播放的接口
  play() { this.player.play() }
  pause() { this.player.pause() }
  stop() { this.player.stop() }

  // 将乐谱转换为字符串表示
  toString() {
    return [this.head, this.body].join('\n\n')
  }

  // 将乐谱转换为JSON格式
  toJSON() {
    const { head, body } = this
    return { head, body }
  }

  // 导出乐谱为Mxl格式
  toMxl = toMxl

  // 静态方法，从Mxl格式导入乐谱
  static fromMxl = fromMxl
}
